package com.g.ocache.index;

import java.util.List;

import com.g.ocache.Cache;
import com.g.ocache.index.criterion.Criterion;


/**
 * Index is for non-pk and range query on the cache.
 * <p/>
 * The index creation is based on the {@link IndexBuilder}.
 * The implementation of the {@link IndexBuilder} describe
 * that how many {@link Criterions} to create for the index
 * and what are they. And also specified the comparator to
 * support the range query.
 * <p/>
 * {@link IndexLoader} to initialize the index if needed.
 * 
 * @author zhangyf
 * @param <K>
 * @param <V>
 */
public interface Index<K, V> {
	
	/**
	 * Whether or not the cache is started.
	 * 
	 * @return true if the cache has been started.
	 */
	boolean isRunning();

	/**
	 * Start the index.
	 * 
	 * @throws Exception
	 */
	void start() throws Exception;

	/**
	 * Stop the index.
	 * 
	 * @throws Exception
	 */
	void stop() throws Exception;
	
	/**
	 * Get the name of the index.
	 * The name is also the identity of the index in cache.
	 * 
	 * @return name
	 */
	String getName();
	
	/**
	 * Get the cache which associated with the index.
	 * 
	 * @return cache
	 */
	Cache<K, V> getCache();
	
	/**
	 * Bind the index to the specified cache.
	 * 
	 * @param cache
	 */
	void setCache(Cache<K, V> cache);
	
	/**
	 * Get the IndexLoader.
	 * 
	 * @return {@link IndexLoader}
	 */
	IndexLoader<K, V> getLoader();
	
	/**
	 * Get the IndexBuilder
	 * 
	 * @return {@link IndexBuilder}
	 */
	IndexBuilder<K, V> getBuilder();
	
	/**
	 * Clear the index.
	 */
	void clear();
	
	/**
	 * Add a value to index.
	 * 
	 * @param key
	 * @param value
	 * @return true if the value is added.
	 */
	boolean add(K key, V value);
	
	/**
	 * Remove a value from the index.
	 * 
	 * @param key
	 * @param value
	 * @return true if the value is removed.
	 */
	boolean remove(K key, V value);
	
	/**
	 * Count the size of entries match the specified {@link Criterion} in index.
	 * 
	 * @param criteria
	 * @return
	 */
	int count(Criterion... criteria);
	
	/**
	 * Query the values that match the specified {@link Criterion}.
	 * 
	 * @param criteria
	 * @return the values
	 */
	List<V> query(Criterion... criteria);
	
	/**
	 * Query the values that match the specified {@link Criterion}.
	 * 
	 * @param from from row
	 * @param criteria
	 * @return the values
	 */
	List<V> query(int from, Criterion... criteria);
	
	/**
	 * Query the values that match the specified {@link Criterion}.
	 * 
	 * @param from from row
	 * @param to to row
	 * @param criteria
	 * @return the values
	 */
	List<V> query(int from, int to, Criterion... criteria);
}
